﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace SerialServerManager
{
    public partial class FrmMain : Form
    {
        // 引入 Windows API：暂停/恢复控件绘制
        [DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
        private const int WM_SETREDRAW = 0x000B;

        private readonly List<SerialServerItem> _serverItems = new List<SerialServerItem>();
        private int _nextId = 1;
        private Timer _rateTimer;

        // 手动声明状态栏标签字段（解决 CS0103 错误）
        private ToolStripLabel _lblTotalSendBytes;
        private ToolStripLabel _lblTotalWriteBytes;

        public FrmMain()
        {
            InitializeComponent();
            InitializeListView();
            LoadTestData();
            InitializeRateTimer();
            InitializeStatusStrip();  // 初始化状态栏（创建标签并添加）
            UpdateStatusStrip();       // 初始更新状态栏
        }

        #region 状态栏初始化与更新（核心统计 + 版本号 + 总字节数）
        // 初始化状态栏控件（动态创建标签，版本号在最后）
        private void InitializeStatusStrip()
        {
            // 清空状态栏原有项（避免设计器中已有项导致顺序混乱）
            _statusStrip.Items.Clear();

            // 1. 创建「总服务器数」标签（第一个）
            if (_lblTotal == null)
            {
                _lblTotal = new ToolStripStatusLabel("总服务器数：0");
                _lblTotal.Margin = new Padding(5, 0, 15, 0); // 左右间距，避免拥挤
            }
            else
            {
                _lblTotal.Text = "总服务器数：0";
                _lblTotal.Margin = new Padding(5, 0, 15, 0);
            }
            _statusStrip.Items.Add(_lblTotal);

            // 2. 创建「在线」标签（第二个）
            if (_lblOnline == null)
            {
                _lblOnline = new ToolStripStatusLabel("在线：0");
                _lblOnline.Margin = new Padding(5, 0, 15, 0);
            }
            else
            {
                _lblOnline.Text = "在线：0";
                _lblOnline.Margin = new Padding(5, 0, 15, 0);
            }
            _statusStrip.Items.Add(_lblOnline);

            // 3. 创建「离线」标签（第三个）
            if (_lblOffline == null)
            {
                _lblOffline = new ToolStripStatusLabel("离线：0");
                _lblOffline.Margin = new Padding(5, 0, 15, 0);
            }
            else
            {
                _lblOffline.Text = "离线：0";
                _lblOffline.Margin = new Padding(5, 0, 15, 0);
            }
            _statusStrip.Items.Add(_lblOffline);

            // 4. 创建「总发送字节数」标签（第四个）
            _lblTotalSendBytes = new ToolStripLabel("总发送：0 B");
            _lblTotalSendBytes.Margin = new Padding(5, 0, 15, 0);
            _statusStrip.Items.Add(_lblTotalSendBytes);

            // 5. 创建「总写入字节数」标签（第五个）
            _lblTotalWriteBytes = new ToolStripLabel("总写入：0 B");
            _lblTotalWriteBytes.Margin = new Padding(5, 0, 15, 0);
            _statusStrip.Items.Add(_lblTotalWriteBytes);

            // 6. 创建「版本号」标签（最后一个）
            if (_lblVersion == null)
            {
                _lblVersion = new ToolStripStatusLabel("版本号：vUnknown");
                _lblVersion.Margin = new Padding(5, 0, 5, 0);
                // 设置版本号标签居右（可选，更美观）
                _lblVersion.Alignment = ToolStripItemAlignment.Right;
            }
            else
            {
                string version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "Unknown";
                _lblVersion.Text = $"版本号：v{version}";
                _lblVersion.Margin = new Padding(5, 0, 5, 0);
                _lblVersion.Alignment = ToolStripItemAlignment.Right;
            }
            _statusStrip.Items.Add(_lblVersion);

            // 确保状态栏填满窗体宽度
            _statusStrip.Stretch = true;
        }

        // 更新状态栏统计数据（实时同步：服务器状态 + 总字节数）
        private void UpdateStatusStrip()
        {
            if (_statusStrip.InvokeRequired)
            {
                _statusStrip.Invoke(new Action(UpdateStatusStrip));
                return;
            }

            // 安全检查：确保所有标签都已初始化
            if (_lblTotal == null || _lblOnline == null || _lblOffline == null ||
                _lblTotalSendBytes == null || _lblTotalWriteBytes == null || _lblVersion == null)
            {
                return;
            }

            // 1. 服务器状态统计
            int total = _serverItems.Count;
            int online = _serverItems.Count(s => s.IsOnline);
            int offline = total - online;

            // 2. 总收发字节数统计（所有服务器累加）
            long totalSendBytes = _serverItems.Sum(s => s.TotalSendBytes);
            long totalWriteBytes = _serverItems.Sum(s => s.TotalWriteBytes);

            // 3. 更新标签文本（字节数自动换算单位）
            _lblTotal.Text = $"总服务器数：{total}";
            _lblOnline.Text = $"在线：{online}";
            _lblOffline.Text = $"离线：{offline}";
            _lblTotalSendBytes.Text = $"总发送：{FormatByteSize(totalSendBytes)}";
            _lblTotalWriteBytes.Text = $"总写入：{FormatByteSize(totalWriteBytes)}";

            // 版本号只在初始化时设置，这里保持不变（避免重复计算）
        }

        // 字节数格式化（自动换算 B/KB/MB/GB）
        private string FormatByteSize(long bytes)
        {
            if (bytes < 1024) return $"{bytes} B";
            if (bytes < 1024 * 1024) return $"{(bytes / 1024.0):F1} KB";
            if (bytes < 1024 * 1024 * 1024) return $"{(bytes / (1024.0 * 1024)):F1} MB";
            return $"{(bytes / (1024.0 * 1024 * 1024)):F1} GB";
        }
        #endregion

        private void InitializeRateTimer()
        {
            _rateTimer = new Timer();
            _rateTimer.Interval = 1000;  // 每秒更新一次速率
            _rateTimer.Tick += RateTimer_Tick;
            _rateTimer.Start();
        }

        private void InitializeListView()
        {
            lvServers.View = View.Details;
            lvServers.FullRowSelect = true;
            lvServers.GridLines = true;
            lvServers.MultiSelect = false;

            // 通过反射设置双缓冲（解决保护级别问题，避免控件闪烁）
            SetControlDoubleBuffered(lvServers);

            // 添加列表列（修改速率列文本，明确标注字节/秒）
            lvServers.Columns.Add("ID", 50);
            lvServers.Columns.Add("COM", 60);
            lvServers.Columns.Add("IP", 120);
            lvServers.Columns.Add("PORT", 70);
            lvServers.Columns.Add("发送速率(字节/秒)", 120);  // 明确列含义
            lvServers.Columns.Add("写入速率(字节/秒)", 120);  // 明确列含义
            lvServers.Columns.Add("状态", 80);
            lvServers.Columns.Add("累计发送", 120);  // 新增累计发送字节列
            lvServers.Columns.Add("累计写入", 120);  // 新增累计写入字节列

            // 调整列宽（自动适应内容）
            foreach (ColumnHeader col in lvServers.Columns)
            {
                col.Width = -2;
            }

            // 初始化右键菜单
            var contextMenu = new ContextMenuStrip();
            var tsAdd = new ToolStripMenuItem("添加服务器");
            var tsDelete = new ToolStripMenuItem("删除选中");
            var tsStart = new ToolStripMenuItem("启动服务");
            var tsStop = new ToolStripMenuItem("停止服务");
            var tsResetCounter = new ToolStripMenuItem("重置统计");  // 新增重置统计菜单

            // 绑定菜单事件
            tsAdd.Click += TsAdd_Click;
            tsDelete.Click += TsDelete_Click;
            tsStart.Click += TsStart_Click;
            tsStop.Click += TsStop_Click;
            tsResetCounter.Click += TsResetCounter_Click;  // 绑定重置统计事件

            // 构建菜单结构
            contextMenu.Items.Add(tsAdd);
            contextMenu.Items.Add(new ToolStripSeparator());
            contextMenu.Items.Add(tsStart);
            contextMenu.Items.Add(tsStop);
            contextMenu.Items.Add(new ToolStripSeparator());
            contextMenu.Items.Add(tsResetCounter);  // 添加重置统计菜单
            contextMenu.Items.Add(tsDelete);

            // 菜单显示前更新状态
            contextMenu.Opening += (s, e) =>
            {
                var hasSelection = lvServers.SelectedItems.Count > 0;
                tsDelete.Enabled = hasSelection;
                tsResetCounter.Enabled = hasSelection;  // 有选中项才启用重置统计
                tsStart.Enabled = false;
                tsStop.Enabled = false;

                if (hasSelection)
                {
                    var server = GetSelectedServer();
                    if (server != null)
                    {
                        tsStart.Enabled = !server.IsOnline;
                        tsStop.Enabled = server.IsOnline;
                    }
                }
            };

            lvServers.ContextMenuStrip = contextMenu;
        }

        // 反射设置双缓冲（解决 ListView.DoubleBuffered 保护级别问题）
        private void SetControlDoubleBuffered(Control control)
        {
            if (control == null || DesignMode)
                return;

            PropertyInfo doubleBufferedProp = typeof(Control).GetProperty(
                "DoubleBuffered",
                BindingFlags.Instance | BindingFlags.NonPublic
            );

            doubleBufferedProp?.SetValue(control, true, null);
        }

        // 速率格式化（字节/秒 → 自动换算 B/s/KB/s/MB/s）
        private string FormatByteRate(int bytesPerSecond)
        {
            if (bytesPerSecond < 1024) return $"{bytesPerSecond} B/s";
            if (bytesPerSecond < 1024 * 1024) return $"{(bytesPerSecond / 1024.0):F1} KB/s";
            return $"{(bytesPerSecond / (1024.0 * 1024)):F1} MB/s";
        }

        // 获取选中的服务器
        private SerialServerItem GetSelectedServer()
        {
            if (lvServers.SelectedItems.Count == 0) return null;
            if (int.TryParse(lvServers.SelectedItems[0].SubItems[0].Text, out int id))
            {
                return _serverItems.Find(item => item.Id == id);
            }
            return null;
        }

        // 加载测试数据（DEBUG模式下）
        private void LoadTestData()
        {
#if DEBUG
            _serverItems.Add(new SerialServerItem
            {
                Id = _nextId++,
                Config = new SerialConfig
                {
                    ComPort = "COM1",
                    IpAddress = "192.168.1.100",
                    Port = 8080,
                    BaudRate = 9600,
                    DataBits = 8,
                    Parity = Parity.None,
                    StopBits = StopBits.One
                }
            });

            _serverItems.Add(new SerialServerItem
            {
                Id = _nextId++,
                Config = new SerialConfig
                {
                    ComPort = "COM2",
                    IpAddress = "192.168.1.101",
                    Port = 8081,
                    BaudRate = 115200,
                    DataBits = 8,
                    Parity = Parity.None,
                    StopBits = StopBits.One
                }
            });
            _serverItems.Add(new SerialServerItem
            {
                Id = _nextId++,
                Config = new SerialConfig
                {
                    ComPort = "COM3",
                    IpAddress = "192.168.128.79",
                    Port = 8082,
                    BaudRate = 115200,
                    DataBits = 8,
                    Parity = Parity.None,
                    StopBits = StopBits.One
                }
            });

            UpdateListView();
#endif
        }

        // 更新列表显示（添加/删除/状态变化时调用）
        private void UpdateListView()
        {
            // 暂停 ListView 绘制，避免闪烁
            SendMessage(lvServers.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
            try
            {
                lvServers.Items.Clear();
                foreach (var item in _serverItems)
                {
                    var lvi = new ListViewItem(item.Id.ToString());
                    lvi.SubItems.Add(item.Config.ComPort);
                    lvi.SubItems.Add(item.Config.IpAddress);
                    lvi.SubItems.Add(item.Config.Port.ToString());
                    lvi.SubItems.Add(FormatByteRate(0));  // 初始速率为0
                    lvi.SubItems.Add(FormatByteRate(0));  // 初始速率为0
                    lvi.SubItems.Add(item.IsOnline ? "在线" : "离线");  // 中文状态更直观
                    lvi.SubItems.Add(FormatByteSize(0));  // 初始累计发送为0
                    lvi.SubItems.Add(FormatByteSize(0));  // 初始累计写入为0

                    // 设置状态颜色（在线绿色，离线浅红色）
                    lvi.BackColor = item.IsOnline ? Color.LightGreen : Color.LightSalmon;
                    // 状态文字颜色（增强对比度）
                    lvi.SubItems[6].ForeColor = item.IsOnline ? Color.DarkGreen : Color.DarkRed;
                    lvServers.Items.Add(lvi);
                }

                // 调整列宽（自动适应内容）
                foreach (ColumnHeader col in lvServers.Columns)
                {
                    col.Width = -2;
                }
            }
            finally
            {
                // 恢复绘制并刷新，同时更新状态栏
                SendMessage(lvServers.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
                lvServers.Refresh();
                UpdateStatusStrip();
            }
        }

        // 右键菜单：添加服务器
        private void TsAdd_Click(object sender, EventArgs e)
        {
            var frm = new FrmAddServer();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                // 校验端口是否已存在（避免重复）
                bool isPortDuplicate = _serverItems.Exists(s => s.Config.Port == frm.Config.Port);
                if (isPortDuplicate)
                {
                    MessageBox.Show($"端口 {frm.Config.Port} 已被占用，请选择其他端口！",
                        "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // 添加新服务器（包含所有串口参数）
                _serverItems.Add(new SerialServerItem
                {
                    Id = _nextId++,
                    Config = frm.Config
                });
                UpdateListView();
            }
        }

        // 右键菜单：删除选中服务器
        private void TsDelete_Click(object sender, EventArgs e)
        {
            var server = GetSelectedServer();
            if (server == null) return;

            // 正在运行的服务需要先停止
            if (server.IsOnline)
            {
                if (MessageBox.Show("选中的服务正在运行，删除前将自动停止，是否继续？",
                    "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
                    return;
                server.Stop();
            }

            // 移除服务器并更新列表
            _serverItems.Remove(server);
            UpdateListView();
        }

        // 右键菜单：启动服务
        private void TsStart_Click(object sender, EventArgs e)
        {
            var server = GetSelectedServer();
            if (server == null) return;

            try
            {
                server.Start();
                MessageBox.Show($"服务 {server.Config.ComPort}（{server.Config.IpAddress}:{server.Config.Port}）启动成功",
                    "操作成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                UpdateListView();  // 启动后更新状态和初始统计
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "启动失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 右键菜单：停止服务
        private void TsStop_Click(object sender, EventArgs e)
        {
            var server = GetSelectedServer();
            if (server == null) return;

            server.Stop();
            MessageBox.Show($"服务 {server.Config.ComPort}（{server.Config.IpAddress}:{server.Config.Port}）已停止",
                "操作成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            UpdateListView();  // 停止后更新状态和统计
        }

        // 右键菜单：重置统计（新增）
        private void TsResetCounter_Click(object sender, EventArgs e)
        {
            var server = GetSelectedServer();
            if (server == null) return;

            if (MessageBox.Show("是否重置该服务器的收发统计数据？",
                "确认重置", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                server.ResetCounters();
                UpdateDynamicColumns();  // 立即更新显示
                UpdateStatusStrip();     // 更新状态栏总统计
            }
        }

        // 顶部添加按钮（与右键菜单添加功能一致）
        private void btnAdd_Click(object sender, EventArgs e)
        {
            TsAdd_Click(sender, e);
        }

        // 窗体关闭时清理资源
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 停止并释放定时器
            _rateTimer?.Stop();
            _rateTimer?.Dispose();

            // 停止所有正在运行的服务
            foreach (var server in _serverItems)
            {
                if (server.IsOnline)
                    server.Stop();
            }
        }

        // 速率定时器 Tick 事件（每秒更新速率和累计字节数）
        private void RateTimer_Tick(object sender, EventArgs e)
        {
            if (lvServers.InvokeRequired)
            {
                lvServers.Invoke(new Action(() => RateTimer_Tick(sender, e)));
                return;
            }

            // 1. 计算所有服务器的当前速率
            foreach (var server in _serverItems)
            {
                server.CalculateRates();
            }

            // 2. 更新速率列和累计字节列（避免重建整个列表）
            UpdateDynamicColumns();

            // 3. 更新状态栏（包含总字节数）
            UpdateStatusStrip();
        }

        // 更新动态列（速率 + 累计字节数）
        private void UpdateDynamicColumns()
        {
            // 暂停 ListView 绘制，减少闪烁
            SendMessage(lvServers.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
            try
            {
                foreach (ListViewItem item in lvServers.Items)
                {
                    if (int.TryParse(item.SubItems[0].Text, out int id))
                    {
                        var server = _serverItems.Find(s => s.Id == id);
                        if (server != null)
                        {
                            // 列4：发送速率（字节/秒，自动换算单位）
                            item.SubItems[4].Text = FormatByteRate(server.SendRate);
                            // 列5：写入速率（字节/秒，自动换算单位）
                            item.SubItems[5].Text = FormatByteRate(server.WriteRate);
                            // 列7：累计发送字节数
                            item.SubItems[7].Text = FormatByteSize(server.TotalSendBytes);
                            // 列8：累计写入字节数
                            item.SubItems[8].Text = FormatByteSize(server.TotalWriteBytes);
                        }
                    }
                }
            }
            finally
            {
                // 恢复绘制并刷新
                SendMessage(lvServers.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
                lvServers.Refresh();
            }
        }
    }
}